/**
 *****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-7-10 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-7-10		Created.
 ****************************************************************************
 **/
package com.me.server;

import com.me.server.JTalkerMember.Message;
import com.me.server.MessageParser.OneMember;

/**
 * 
 * <br/>
 * 上午8:25:12 2012-7-10
 * 
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class JTalkProtocal {

//	private JTalkServerThread parent = null;
//	private JTalkServer parent = null;
	private JTalkerMember parent = null;
	private MessageParser parser = null;

	private final static int WAITING = 0;
	private final static int LOGGING = 1;
	private final static int GET_PACKAGE = 2;
	private int state = WAITING;

	public boolean closeConnectionNow = false;

//	public JTalkProtocal(JTalkServerThread parent) {
//		this.parent = parent;
//		parser = new MessageParser();
//	}
	
	public JTalkProtocal(JTalkerMember parent) {
		this.parent = parent;
		this.parser = new MessageParser();
	}

	/**
	 * 解析接收到消息.
	 * 
	 * @param message
	 */
	public String processInput(String message) {
		// TODO Auto-generated method stub
		JTalkerMember member = null;
		String messageOutput = null;
		this.closeConnectionNow = false;
		if (state == WAITING) {
			this.state = LOGGING;
			messageOutput = "<JTALKER>" + "<" + JTalkServer.MESSAGE + " content=\"Welcome on JTalk-Server "
					+ JTalkServer.VERSION + "\" type=\"info\"/></JTALKER>";
		} else if (state == LOGGING) {
			if (!parser.parsing(message)) {
				this.state = LOGGING;
				messageOutput = "<JTALKER><" + MessageParser.MESSAGE
						+ " content=\"[ERROR] Wrong Protocol! Try again!\" type=\"error\"/></JTALKER>";
			} else {
				if (parser.isNewMember()) { // 新注册用户
					String userName = parser.getAMember(0).name;
					String password = parser.getAMember(0).passwd;
					if (!this.parent.parent.addGlobalUser(userName, password)) {
						messageOutput = "<JTALKER><"
								+ MessageParser.MESSAGE
								+ " content=\"[ERROR] Can't create account - user exists or the name is not wellformed "
								+ "(only letters and numbers are allowed). Sorry.\" type=\"error\"/></JTALKER>";
					} else {
						messageOutput = "<JTALKER><" + MessageParser.MESSAGE
								+ " content=\"[INFO] Account successfull created. Welcome.\" type=\"info\"/></JTALKER>";
					}
					this.state = LOGGING;
					this.closeConnectionNow = true;
				} else { // 用户登录
					OneMember oneMember = parser.getAMember(0);
					// member = this.parent.parent.getMember(oneMember.name);
					if(this.parent.parent.login(oneMember)){
						
						this.parent.setLogin(true); // 标记用户已登录.
						this.parent.setUserName(oneMember.name);
						this.parent.setUserType(oneMember.type);
						this.parent.setUserSID(oneMember.sid);
						
						messageOutput = "<JTALKER>";
						messageOutput += this.parent.parent.getXMLMemberList(this.parent);
						messageOutput += "</JTALKER>";
						
						this.parent.parent.sendUpdateRequestToAll(oneMember.name);
						state = GET_PACKAGE;
					}
					// this.parent.setMemberInfo(oneMember.name, oneMember.passwd, oneMember.type, oneMember.sid);
				}
			}
		} else if (state == GET_PACKAGE) {
			if (message.startsWith("<JTALKER>") || message.startsWith("<jtalker>")) {
				if (!this.parser.parsing(message)) {
					messageOutput = "<JTALKER><" + MessageParser.MESSAGE
							+ " content=\"[ERROR] Wrong Protocol! Try again!\" type=\"error\"/></JTALKER>";
//					state = GET_PACKAGE;
				} else {
//					member = this.parent.parent.getMember(this.parser.getAMember(0).name);
					member = this.parent;
					if (this.parser.getMemberStatus() != null && !"null".equals(this.parser.getMemberStatus())) {
						member.sendUserStatus(this.parser.getMemberStatus());
					}
					if (this.parser.getReceivers() != null) {
						for (int i = 0; i < this.parser.getReceiversAsArray().length; i++) {
							JTalkerMember tempMem = this.parent.parent.getMember(this.parser.getReceiversAsArray()[i]);
							if (tempMem != null) {
								String tempMessage = this.parser.getMessage();
								if (!tempMem.addMessage(tempMessage, member.getUserName(),
										this.parser.getMessageType(), this.parser.getMessageSubject(),
										this.parser.getMessageID())) {
									System.out.println("*** ERROR: Runtime - can't JTalkerMember.addMessage() from: "
											+ member.getUserName() + " to: " + tempMem.getUserName());
								}
								if (tempMem.isChatRoom()) {
									this.parent.parent.redirectChatroomMessages();
								}
							} else {
								System.out.println("*** Message with wrong receiver recieved, from: "
										+ member.getUserInfo());
								System.out.println("Unknown user: " + this.parser.getReceiversAsArray()[i]);
								member.addMessage(
										"Unknown user:" + this.parser.getReceiversAsArray()[i], "@server", "error",
										null, null);
							}
						}
					}
					// process command.
					if (this.parser.getCommand() != null) {
						String retValCommand = this.parent.parent.getPlugInLoader().invodePlugInMethod(
								this.parser.getCommand(), member, this.parser.getCommandID());
						// System.out.println("-----retValCommand-----" + retValCommand);

						// boolean sendError = false;
						// if (retValCommand == null) {
						// retValCommand = this.parent.parent.getPlugInLoader().getLastError();
						// sendError = true;
						// }
						// add response message
						member.addMessage(toHTMLString(retValCommand), "@server", "command_response",
								null, this.parser.getCommandID());

					}

					messageOutput = "<JTALKER>";
					messageOutput += this.parent.parent.getXMLMemberList(member);
					messageOutput += this.getAllMessagesForUser();
					messageOutput += "</JTALKER>";
					// state = GET_PACKAGE;
				}
			} else {
				messageOutput = "<JTALKER><" + MessageParser.MESSAGE
						+ " content=\"[ERROR] Wrong Protocol! Try again!\" type=\"error\"/></JTALKER>";
//				state = GET_PACKAGE;
			}
		}
		return messageOutput;
	}

	/**
	 * 将消息转换为HTML字符.
	 * 
	 * @param retValCommand
	 * @return
	 */
	private String toHTMLString(String in) {
		StringBuffer out = new StringBuffer();
		for (int i = 0; in != null && i < in.length(); i++) {
			char c = in.charAt(i);
			// ASCI Entity
			if (c == '\'') {
				out.append("&#39;");
			} else if (c == '\"') {
				out.append("&#34;");
			} else if (c == '<') {
				out.append("&lt;");
			} else if (c == '>') {
				out.append("&gt;");
			} else if (c == '&') {
				out.append("&amp;");
			}
			// ISO 8859-1 (DE) Character Entities - incomplete, should be correct
			// handled by the client (char-set)!
			else if (c == '\u00e4') {
				out.append("&#228;");
			} else if (c == '\u00c4') {
				out.append("&#196;");
			} else if (c == '\u00d6') {
				out.append("&#214;");
			} else if (c == '\u00f6') {
				out.append("&#246;");
			} else if (c == '\u00fc') {
				out.append("&#252;");
			} else if (c == '\u00dc') {
				out.append("&#220;");
			} else if (c == '\u00df') {
				out.append("&#223;");
			}
			// New Line killer
			else if (c == '\n') {
				out.append("_");
			} else if (c == '\r') {
				out.append("_");
			} else {
				out.append(c);
			}
		}
		return out.toString();
	}

	/**
	 * 获取一个用户的所有消息.
	 * 
	 * @return
	 */
	private String getAllMessagesForUser() {
		// TODO
		JTalkerMember member = this.parent;
		String retVal = "";
		while (member.numOfMsgs() > 0) {
			Message m = member.getMessage();
			if (m != null) {
				retVal += "<" + MessageParser.MESSAGE + " content=\"" + m.content + "\"";
				if (m.subject != null) {
					retVal += (" subject=\"" + m.subject + "\"");
				}
				retVal += " sender=\"" + m.sender + "\" type=\"" + m.type + "\" id=\"" + m.ID + "\"/>";
			}
		}
		return retVal;
	}

}
